<template>
  <div class="login-form">
    <div class="back-icon" v-if="operateType === 'forget'">
      <span @click="backLogin">
        <arrow-left-outlined class="arrow-left" />
        <span class="back-text">返回账号密码登录</span>
      </span>
    </div>
    <div v-if="operateType === 'login'">
      <div class="form-title"><span class="title-text">账号密码登录</span></div>
      <a-form
        hideRequiredMark
        :colon="false"
        ref="formRef"
        autocomplete="off"
        class="form-data"
        :model="formState"
        :rules="getFormRules"
        @keypress.enter="handleLogin"
        layout="vertical"
      >
        <a-form-item label="账号" name="userAccount">
          <a-input allowClear placeholder="手机号/邮箱/用户名" v-model:value.trim="formState.userAccount"> </a-input>
        </a-form-item>
        <a-form-item label="密码" name="userPwd">
          <a-input-password allowClear placeholder="请输入密码" v-model:value.trim="formState.userPwd">
          </a-input-password>
          <div class="forgetPwd"><span @click="forgetPwd">忘记密码</span></div>
        </a-form-item>

        <a-form-item>
          <a-button
            type="primary"
            class="btn-login"
            :disabled="btnDisabled"
            :loading="btnLoading"
            block
            @click="handleLogin"
            >登 录</a-button
          >
        </a-form-item>
      </a-form>
    </div>
    <div class="forget-form" v-if="operateType === 'forget'">
      <div class="form-title"><span class="title-text">忘记密码</span></div>
      <div v-show="fortgetStep === 1">
        <a-form
          hideRequiredMark
          :colon="false"
          ref="formForgetRef"
          autocomplete="off"
          class="form-data"
          :model="formForgetState"
          :rules="formForgetRules"
          @keypress.enter="handleForget"
          layout="vertical"
        >
          <a-form-item label="手机号" name="contactPhone">
            <a-input allowClear placeholder="请输入手机号" v-model:value.trim="formForgetState.contactPhone"> </a-input>
          </a-form-item>
          <a-form-item label="图形验证码" name="captchaCode">
            <a-input
              allowClear
              :maxlength="6"
              placeholder="请输入图形验证码"
              v-model:value.trim="formForgetState.captchaCode"
            >
              <template #addonAfter>
                <div class="code-captcha" @click="getCaptcha">
                  <a-image :src="codeObj.image" :width="112" :height="40" :preview="false" />
                </div>
              </template>
            </a-input>
          </a-form-item>
          <a-form-item label="短信验证码" name="smsCode">
            <CountDownInput
              allowClear
              :maxlength="6"
              :count="120"
              customClass="light-code"
              v-model:value="formForgetState.smsCode"
              placeholder="请输入验证码"
              :sendCodeApi="sendCodeApi"
            />
          </a-form-item>
          <a-form-item>
            <a-button
              type="primary"
              class="btn-forget"
              :disabled="forgetDisabled"
              :loading="forgetBtnLoading"
              block
              @click="handleForget"
              >验 证</a-button
            >
          </a-form-item>
        </a-form>
      </div>
      <div v-show="fortgetStep === 2">
        <a-form
          hideRequiredMark
          :colon="false"
          ref="formConfirmRef"
          autocomplete="off"
          class="form-data"
          layout="vertical"
          validateTrigger="blur"
          :model="formConfirmState"
          :rules="getConfirmRules"
          @keypress.enter="handleConfirm"
        >
          <a-form-item label="新密码" name="newPassword">
            <a-input-password
              allowClear
              :maxlength="16"
              placeholder="请输入6-16位密码，区分大小写"
              v-model:value.trim="formConfirmState.newPassword"
            >
            </a-input-password>
          </a-form-item>
          <a-form-item label="确认密码" name="confirmPassword">
            <a-input-password
              allowClear
              :maxlength="16"
              placeholder="请再次输入新密码"
              v-model:value.trim="formConfirmState.confirmPassword"
            >
            </a-input-password>
          </a-form-item>
          <a-form-item>
            <div class="confirm-box">
              <a-button type="primary" class="btn-back" @click="handleBack">上一步</a-button>
              <a-button
                type="primary"
                class="btn-confirm"
                :disabled="confirmDisabled"
                :loading="confirmBtnLoading"
                @click="handleConfirm"
                >确 认</a-button
              >
            </div>
          </a-form-item>
        </a-form>
      </div>
      <div class="back-login"><span @click="backLogin">返回登录</span></div>
    </div>
  </div>
  <!-- <ForgetPwd @register="forgetPwdRegister" /> -->
</template>

<script setup lang="ts">
import { ref, reactive, unref, watch, computed, onMounted } from 'vue'
import type { RouteLocationNormalizedLoaded, LocationQuery } from 'vue-router'
import { message } from 'ant-design-vue'
import { userStore } from '@/store/modules/user'
import { permissionStore } from '@/store/modules/permission'
import type { RouteRecordRaw } from 'vue-router'
import CountDownInput from '@/components/CountDown/CountDownInput.vue'
import { router } from '@/router'
import { useGoPage } from '@/hooks/useGoPage'
import { useRouter } from 'vue-router'
import { ArrowLeftOutlined } from '@ant-design/icons-vue'
import api from '@/api'
import { Rule } from 'ant-design-vue/es/form'
import { encryptorPwd } from '@/utils/jsencrypt'
import { pattern } from '@/utils/validate'
const { getImageCaptcha, getSmsCode, validSmsCode, updateForgetPwd } = api

const userModule = userStore()
const permissionModule = permissionStore()
const goPage = useGoPage()
const { currentRoute } = useRouter()

const operateType = ref('login')
const fortgetStep = ref(1)
const validId = ref(1)

const formState = reactive({
  userAccount: '',
  userPwd: '',
  loginType: '0'
})
const formForgetState = reactive({
  contactPhone: '',
  smsCode: '',
  captchaCode: ''
})
const formConfirmState = reactive({
  newPassword: '',
  confirmPassword: ''
})
function resetForgetForm() {
  formConfirmState.confirmPassword = ''
  formConfirmState.newPassword = ''
  formForgetState.contactPhone = ''
  formForgetState.smsCode = ''
  formForgetState.captchaCode = ''
}
const codeObj = reactive({
  code: '',
  image: '',
  imageKey: ''
})
const btnLoading = ref(false)
const forgetBtnLoading = ref(false)
const confirmBtnLoading = ref(false)
const formRef = ref()
const formForgetRef = ref()
const formConfirmRef = ref()
const queryParam = reactive({
  redirect: '',
  otherQuery: {}
})

let validatePass = async (rule: Rule, value: string) => {
  if (!value) {
    return Promise.reject('请输入确认密码')
  } else if (value !== formConfirmState.newPassword) {
    return Promise.reject('两次输入的密码不一致')
  } else {
    return Promise.resolve()
  }
}
let validatePassNew = async (rule: Rule, value: string) => {
  const regex = /^(?=.*\d)(?=.*[a-zA-Z]).{6,16}$/
  const regex2 = /[\u4e00-\u9fff]/ //不允许汉字
  if (!value) {
    return Promise.reject('请输入新密码')
  } else if (!regex.test(value) || regex2.test(value)) {
    return Promise.reject('密码由6~16位字符组成，至少包含数字和字母，区分大小写。')
  } else {
    return Promise.resolve()
  }
}
let validatePhone = async (rule: Rule, value: string) => {
  if (!value) {
    return Promise.reject('请输入手机号')
  } else if (!pattern.regexp_cell_phone.test(value)) {
    return Promise.reject('请输入正确的手机号')
  }
}
const getFormRules = {
  userAccount: [{ required: true, message: '请输入账号', trigger: 'blur' }],
  userPwd: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}

const formForgetRules = {
  contactPhone: [{ required: true, validator: validatePhone, trigger: 'blur' }],
  smsCode: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
  captchaCode: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
}
const getConfirmRules = {
  newPassword: [{ required: true, validator: validatePassNew, trigger: 'blur' }],
  confirmPassword: [{ required: true, validator: validatePass, trigger: 'blur' }]
}

const btnDisabled = computed(() => !(formState.userAccount && formState.userPwd))
const confirmDisabled = computed(
  () =>
    !(
      formConfirmState.confirmPassword &&
      formConfirmState.newPassword &&
      formConfirmState.newPassword.length > 5 &&
      formConfirmState.newPassword.length < 17 &&
      formConfirmState.confirmPassword === formConfirmState.newPassword
    )
)
const forgetDisabled = computed(
  () =>
    !(
      formForgetState.contactPhone &&
      formForgetState.captchaCode &&
      formForgetState.smsCode &&
      pattern.regexp_cell_phone.test(formForgetState.contactPhone)
    )
)

// const [forgetPwdRegister, { openModal: forgetPwdOpenModal, setModalProps }] = useModal()
watch(
  () => currentRoute.value,
  (route: RouteLocationNormalizedLoaded) => {
    // 监听的是整个watch对象
    btnLoading.value = false
    if (route.query) {
      queryParam.redirect = route.query.redirect as string
      queryParam.otherQuery = getOtherQuery(route.query)
    }
  },
  {
    immediate: true
  }
)

// 获取图形验证码
const getCaptcha = async () => {
  let res = await getImageCaptcha()
  if (res.result) {
    codeObj.image = res.result.image
    codeObj.imageKey = res.result.key
  }
}

// 发送短信验证码
const sendCodeApi = async () => {
  try {
    await unref(formForgetRef).validate(['contactPhone'])
    await unref(formForgetRef).validate(['captchaCode'])
    await getSmsCode({
      phoneNumber: formForgetState.contactPhone,
      key: codeObj.imageKey,
      imageCode: formForgetState.captchaCode
    })
    message.success('验证码已发送，请查收')
    return true
  } catch (error) {
    getCaptcha()
    return false
  }
}
onMounted(() => {
  getCaptcha()
})
function getOtherQuery(query: LocationQuery) {
  return Object.keys(query).reduce((acc: LocationQuery, cur) => {
    if (cur !== 'redirect') {
      acc[cur] = query[cur]
    }
    return acc
  }, {})
}
async function forgetPwd() {
  operateType.value = 'forget'
}
async function handleLogin() {
  const data = await unref(formRef).validate()
  if (data) {
    btnLoading.value = true
    try {
      let res = await userModule.login(formState)
      // btnLoading.value = false
      goPage({
        path: queryParam.redirect || '/',
        query: queryParam.otherQuery
      })
    } catch (error) {
      btnLoading.value = false
    }
  }
}
// 忘记密码-第一步校验
async function handleForget() {
  const data = await unref(formForgetRef).validate()
  if (data) {
    try {
      forgetBtnLoading.value = true
      let res = await validSmsCode({
        phoneNumber: formForgetState.contactPhone,
        smsCode: formForgetState.smsCode
      })
      if (res.result.validId) {
        validId.value = res.result.validId
      }
      forgetBtnLoading.value = false
      fortgetStep.value = 2
    } catch (error) {
      forgetBtnLoading.value = false
    }
  }
}
// 忘记密码-返回登录
function backLogin() {
  fortgetStep.value = 1
  operateType.value = 'login'
  resetForgetForm()
  getCaptcha()
}
// 忘记密码-第二步更新密码
async function handleConfirm() {
  console.log('确认密码')
  try {
    await unref(formConfirmRef).validate()
    confirmBtnLoading.value = true
    await updateForgetPwd({
      newPwd: encryptorPwd(formConfirmState.confirmPassword),
      phoneNumber: formForgetState.contactPhone,
      validId: validId.value
    })
    message.success('密码重置成功，请点击上方返回账号密码登录')
    confirmBtnLoading.value = false
  } catch (error) {
    confirmBtnLoading.value = false
  }
}
function handleBack() {
  fortgetStep.value = 1
}
</script>

<style lang="less" scoped>
.login-form {
  width: 42%;
  min-width: 400px;
  .back-icon {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: 8px 0;
    border-bottom: 1px solid #e0e1e6;
    span {
      cursor: pointer;
    }
    .arrow-left {
      margin: 0 21px;
    }
    .back-text {
      height: 40px;
      font-size: 16px;
      font-family: PingFangSC, PingFang SC;
      font-weight: 600;
      color: #192235;
      line-height: 40px;
    }
  }
  .form-title {
    font-size: 20px;
    line-height: 40px;
    padding-bottom: 15px;
    font-weight: bold;
    margin-bottom: 24px;
    border-bottom: 1px solid #e0e1e6;
    .title-text {
      position: relative;
      &::after {
        content: '';
        position: absolute;
        left: calc(50% - 10px);
        bottom: -25px;
        width: 20px;
        height: 4px;
        background: @primary-color;
        border-radius: 10px 10px 0 0;
      }
    }
  }
  :deep(.form-data) {
    .ant-form-item {
      margin-bottom: 24px;
      &.ant-form-item-with-help {
        margin-bottom: 0px;
      }
      .ant-form-item-label {
        padding-bottom: 0;
      }
      .ant-form-item-label > label {
        height: 22px;
        line-height: 22px;
      }
      .ant-input-affix-wrapper {
        height: 40px;
        border-radius: 4px;
        padding: 4px 16px;
      }
    }
    .light-code {
      background: #4aa353;
      color: #fff;
      border-color: #4aa353;
      padding: 4px 16px;
      border-radius: 4px;
      width: 112px;
      &[disabled] {
        color: #fff;
        background: #cdcdcd;
        border-color: #cdcdcd;
      }
    }
    .btn-login {
      height: 40px;
      font-weight: 500;
      font-size: 18px;
      border-radius: 4px;
      margin-top: 102px;
      margin-bottom: 16px;
      padding: 4px 16px;
    }
    .confirm-box {
      display: flex;
      margin-top: 102px;
      .btn-back {
        height: 40px;
        font-weight: 500;
        font-size: 18px;
        border-radius: 4px;
        padding: 4px 16px;
        margin-right: 8px;
        width: 96px;
        color: #4aa353;
        background: transparent;
      }
      .btn-confirm {
        height: 40px;
        font-weight: 500;
        font-size: 18px;
        border-radius: 4px;
        padding: 4px 16px;
        flex: 1;
      }
    }
    .btn-forget {
      height: 40px;
      font-weight: 500;
      font-size: 18px;
      border-radius: 4px;
      margin-top: 16px;
      padding: 4px 16px;
    }
    .ant-input-group-addon {
      padding-left: 8px;
      padding-right: 0;
      background-color: transparent;
      border: none;
      .code-captcha {
        height: 40px;
        position: relative;
        cursor: pointer;
        .ant-image {
          border-radius: 4px;
          overflow: hidden;
          .ant-image-img {
            height: 40px;
          }
        }

        .captcha-refresh {
          width: 112px;
          font-size: 12px;
          color: #989ca6;
          display: flex;
          align-items: center;
          justify-content: space-around;
          position: absolute;
          left: 0;
          bottom: -22px;
        }
      }
    }
    .count-input {
      .ant-btn {
        height: 40px;
      }
    }
  }
  .forgetPwd {
    color: #4aa353;
    text-align: right;
    height: 16px;
    line-height: 16px;
    position: absolute;
    width: 56px;
    right: 0;
    bottom: -24px;
    span {
      cursor: pointer;
    }
  }
  .back-login {
    color: #4aa353;
    text-align: right;
    height: 16px;
    line-height: 16px;
    position: relative;
    bottom: 16px;
    span {
      cursor: pointer;
    }
  }
  .forget-form {
    // position: relative;
    // top: 8px;
  }
}
</style>
